<template>
  <div class="menu-permission-manager">
    <div class="page-header">
      <h2>菜单管理</h2>
      <div class="header-actions">
        <el-button type="primary" @click="showPermissionDialog = true">
          <el-icon><Setting /></el-icon>
          权限配置
        </el-button>
        <el-button @click="refreshData">
          <el-icon><Refresh /></el-icon>
          刷新
        </el-button>
      </div>
    </div>

    <!-- 菜单管理 -->
    <el-card class="menu-card">
      <template #header>
        <div class="card-header">
          <span>菜单结构</span>
          <el-text type="info" size="small">拖拽菜单可调整顺序</el-text>
        </div>
      </template>

      <div class="menu-container" v-loading="loading">
        <MenuTree
          ref="menuTreeRef"
          :menu-data="allMenus"
          :show-checkbox="false"
          :show-actions="true"
          :expand-all="false"
          :draggable="true"
          :expanded-keys="expandedKeys"
          @node-drop="handleMenuDrop"
          @move-up="handleMoveUp"
          @move-down="handleMoveDown"
          @node-expand="handleNodeExpand"
          @node-collapse="handleNodeCollapse"
        />
      </div>
    </el-card>

    <!-- 权限配置对话框 -->
    <el-dialog
      v-model="showPermissionDialog"
      title="菜单权限配置"
      width="600px"
    >
      <div class="permission-config-container">
        <div class="role-selection">
          <h4>选择角色</h4>
          <el-select
            v-model="selectedRoleId"
            placeholder="请选择角色"
            style="width: 100%"
            @change="loadRolePermissions"
          >
            <el-option
              v-for="role in allRoles"
              :key="role.id"
              :label="role.name"
              :value="role.id"
            />
          </el-select>
        </div>

        <div class="menu-selection" v-if="selectedRoleId">
          <h4>菜单权限</h4>
          <MenuTree
            ref="permissionTreeRef"
            :menu-data="allMenus"
            :show-checkbox="true"
            :check-strictly="false"
            :default-checked-keys="currentRoleMenus"
            @check="handlePermissionCheck"
          />
        </div>
      </div>

      <template #footer>
        <el-button @click="showPermissionDialog = false">取消</el-button>
        <el-button type="primary" @click="savePermissions" :loading="saving">
          保存权限
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElLoading } from 'element-plus'
import { Setting, Refresh, Edit } from '@element-plus/icons-vue'
import MenuTree from '@/components/MenuTree.vue'
import { userManagementAPI } from '@/api/userManagement'

// 响应式数据
const loading = ref(false)
const saving = ref(false)
const showPermissionDialog = ref(false)
const selectedRoleId = ref(null)
const currentRoleMenus = ref([])

const allRoles = ref([])
const allMenus = ref([])
const expandedKeys = ref([]) // 保存展开的节点ID

// 模板引用
const menuTreeRef = ref(null)
const permissionTreeRef = ref(null)

// 计算属性
const topLevelMenus = computed(() => {
  return allMenus.value.filter(menu => menu.level === 1).map(menu => ({
    ...menu,
    children: allMenus.value.filter(child => child.parent === menu.id)
  }))
})

// 方法
const loadData = async () => {
  loading.value = true
  try {
    // 加载角色和菜单数据
    const [rolesResponse, menusResponse] = await Promise.all([
      userManagementAPI.getRoles(),
      userManagementAPI.getAllMenus()
    ])

    allRoles.value = rolesResponse.results || rolesResponse
    allMenus.value = menusResponse.results || menusResponse

    console.log('Loaded data:', { roles: allRoles.value, menus: allMenus.value })
  } catch (error) {
    console.error('加载数据失败:', error)
    ElMessage.error('加载数据失败')
  } finally {
    loading.value = false
  }
}

const refreshData = () => {
  loadData()
}

// 处理节点展开
const handleNodeExpand = (data, node) => {
  if (!expandedKeys.value.includes(data.id)) {
    expandedKeys.value.push(data.id)
  }
}

// 处理节点折叠
const handleNodeCollapse = (data, node) => {
  const index = expandedKeys.value.indexOf(data.id)
  if (index > -1) {
    expandedKeys.value.splice(index, 1)
  }
}

// 更新本地菜单排序数据
const updateLocalMenuOrder = (menuOrders) => {
  console.log('更新本地菜单排序，当前展开的节点:', expandedKeys.value)

  // 创建一个映射来快速查找新的排序
  const orderMap = {}
  menuOrders.forEach(order => {
    orderMap[order.id] = order.sort_order
  })

  // 更新本地菜单数据的排序
  allMenus.value.forEach(menu => {
    if (orderMap[menu.id] !== undefined) {
      menu.sort_order = orderMap[menu.id]
    }
  })

  // 重新排序菜单数组
  allMenus.value.sort((a, b) => {
    // 先按层级排序，再按排序号排序
    if (a.level !== b.level) {
      return a.level - b.level
    }
    // 同级菜单按父菜单分组
    if (a.parent !== b.parent) {
      return (a.parent || 0) - (b.parent || 0)
    }
    // 同父菜单按排序号排序
    return a.sort_order - b.sort_order
  })

  console.log('排序更新完成，保持展开状态:', expandedKeys.value)

  // 手动恢复展开状态
  setTimeout(() => {
    if (menuTreeRef.value && menuTreeRef.value.restoreExpandedState) {
      menuTreeRef.value.restoreExpandedState()
    }
  }, 200)
}

// 处理菜单拖拽排序
const handleMenuDrop = async (dragNode, dropNode, dropType) => {
  const loading = ElLoading.service({
    lock: true,
    text: '正在更新菜单排序...',
    background: 'rgba(0, 0, 0, 0.7)'
  })

  try {
    // 重新计算所有菜单的排序
    const menuOrders = calculateNewMenuOrder(dragNode, dropNode, dropType)

    // 调用API更新菜单排序
    await userManagementAPI.updateMenuOrder({ menu_orders: menuOrders })

    // 直接更新本地菜单数据的排序，而不是重新加载
    updateLocalMenuOrder(menuOrders)

    // 通知其他组件菜单已更新（比如导航栏）
    window.dispatchEvent(new CustomEvent('menu-order-updated'))

    loading.close()
    ElMessage.success('菜单排序更新成功')
  } catch (error) {
    console.error('更新菜单排序失败:', error)
    loading.close()
    ElMessage.error('更新菜单排序失败，请重试')

    // 失败时重新加载数据恢复原状态
    await loadData()
  }
}

// 处理向上移动
const handleMoveUp = async (menuData) => {
  await moveMenu(menuData, 'up')
}

// 处理向下移动
const handleMoveDown = async (menuData) => {
  await moveMenu(menuData, 'down')
}

// 移动菜单
const moveMenu = async (menuData, direction) => {
  const loading = ElLoading.service({
    lock: true,
    text: '正在调整菜单顺序...',
    background: 'rgba(0, 0, 0, 0.7)'
  })

  try {
    // 获取同级菜单
    const siblings = getSiblingMenus(menuData)
    const currentIndex = siblings.findIndex(m => m.id === menuData.id)

    if (direction === 'up' && currentIndex === 0) {
      loading.close()
      return // 已经是第一个，不能再向上
    }

    if (direction === 'down' && currentIndex === siblings.length - 1) {
      loading.close()
      return // 已经是最后一个，不能再向下
    }

    // 交换位置
    const targetIndex = direction === 'up' ? currentIndex - 1 : currentIndex + 1
    const menuOrders = []

    siblings.forEach((menu, index) => {
      let newSortOrder
      if (index === currentIndex) {
        newSortOrder = siblings[targetIndex].sort_order
      } else if (index === targetIndex) {
        newSortOrder = siblings[currentIndex].sort_order
      } else {
        newSortOrder = menu.sort_order
      }

      menuOrders.push({
        id: menu.id,
        sort_order: newSortOrder,
        parent_id: menu.parent
      })
    })

    // 调用API更新菜单排序
    await userManagementAPI.updateMenuOrder({ menu_orders: menuOrders })

    // 直接更新本地菜单数据的排序，而不是重新加载
    updateLocalMenuOrder(menuOrders)

    // 通知其他组件菜单已更新
    window.dispatchEvent(new CustomEvent('menu-order-updated'))

    loading.close()
    ElMessage.success('菜单顺序调整成功')
  } catch (error) {
    console.error('调整菜单顺序失败:', error)
    loading.close()
    ElMessage.error('调整菜单顺序失败，请重试')
    await loadData()
  }
}

// 获取同级菜单
const getSiblingMenus = (menuData) => {
  return allMenus.value
    .filter(menu => menu.parent === menuData.parent && menu.level === menuData.level)
    .sort((a, b) => a.sort_order - b.sort_order)
}

// 计算新的菜单排序
const calculateNewMenuOrder = (dragNode, dropNode, dropType) => {
  const menuOrders = []
  const draggedMenu = dragNode.data
  const dropMenu = dropNode.data

  // 只处理同级菜单的排序
  if (draggedMenu.level !== dropMenu.level || draggedMenu.parent !== dropMenu.parent) {
    ElMessage.warning('只能在同级菜单间拖拽排序')
    return []
  }

  // 获取同级菜单
  const siblings = allMenus.value
    .filter(menu => menu.parent === draggedMenu.parent && menu.level === draggedMenu.level)
    .sort((a, b) => a.sort_order - b.sort_order)

  // 移除被拖拽的菜单
  const filteredSiblings = siblings.filter(m => m.id !== draggedMenu.id)

  // 找到目标位置
  const dropIndex = filteredSiblings.findIndex(m => m.id === dropMenu.id)

  // 根据拖拽类型插入到正确位置
  let insertIndex
  if (dropType === 'before') {
    insertIndex = dropIndex
  } else if (dropType === 'after') {
    insertIndex = dropIndex + 1
  } else {
    insertIndex = dropIndex
  }

  // 插入被拖拽的菜单
  filteredSiblings.splice(insertIndex, 0, draggedMenu)

  // 重新分配排序号
  filteredSiblings.forEach((menu, index) => {
    menuOrders.push({
      id: menu.id,
      sort_order: index + 1,
      parent_id: menu.parent
    })
  })

  return menuOrders
}

// 加载角色权限
const loadRolePermissions = async () => {
  if (!selectedRoleId.value) return

  try {
    const response = await userManagementAPI.getRoleMenus(selectedRoleId.value)
    currentRoleMenus.value = response.map(item => item.menu)

    // 设置树形组件的选中状态
    if (permissionTreeRef.value) {
      permissionTreeRef.value.setCheckedKeys(currentRoleMenus.value)
    }
  } catch (error) {
    console.error('加载角色权限失败:', error)
    ElMessage.error('加载角色权限失败')
  }
}

// 处理权限勾选变化
const handlePermissionCheck = (data, checked) => {
  // 实时更新当前角色的菜单权限
  const checkedKeys = permissionTreeRef.value?.getCheckedKeys() || []
  currentRoleMenus.value = checkedKeys
}

// 保存权限配置
const savePermissions = async () => {
  if (!selectedRoleId.value) {
    ElMessage.warning('请选择角色')
    return
  }

  const checkedKeys = permissionTreeRef.value?.getCheckedKeys() || []

  saving.value = true
  try {
    await userManagementAPI.batchAssignMenuPermissions({
      role_id: selectedRoleId.value,
      menu_ids: checkedKeys
    })

    ElMessage.success('权限配置成功')
    showPermissionDialog.value = false
    selectedRoleId.value = null
    currentRoleMenus.value = []
  } catch (error) {
    console.error('保存权限失败:', error)
    ElMessage.error('保存权限失败')
  } finally {
    saving.value = false
  }
}

// 生命周期
onMounted(() => {
  loadData()
})
</script>

<style scoped>
.menu-permission-manager {
  padding: 20px;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.menu-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.menu-container {
  min-height: 500px;
  padding: 24px;
  background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
  border-radius: 12px;
  position: relative;
  overflow: hidden;
}

.menu-container::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background:
    radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.1) 0%, transparent 50%),
    radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.1) 0%, transparent 50%),
    radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.1) 0%, transparent 50%);
  pointer-events: none;
}

.permission-config-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.role-selection h4,
.menu-selection h4 {
  margin: 0 0 12px 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.menu-selection {
  max-height: 400px;
  overflow-y: auto;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 12px;
  background-color: #fafafa;
}
</style>
